package BNS.coloring;

import java.io.File;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Vector;

import BNS.graphs.GraphPack;
import BNS.plumbing.BNSGameController;
import BNS.plumbing.Library;


/** This is an example class that implements a simple graph coloring game.
	The game is solved when all players have colored their node the same as each of their neighbours. 
	It assumes that the colors are integers in {1,2, ..., colorChoices}. 
	The counterpart class in the client machine is ColoringPersona.
	*/
public class ConsensusGame extends ColoringGame {
  //private static final long serialVersionUID = 1L;

  /** Used to construct a game, using parameters from a Tokenizer.
		Conventionally, this (and the constructor) are used to build an
		object to be stored in a file and used in a session later.
		*/
	public static BNSGameController build(String dir, StringTokenizer st) {
		BNSGameController game= null;
		try {
			File gpFile= new File(dir,st.nextToken()+".gpack");
			GraphPack gp= Library.getPack(gpFile);
			if (gp==null) return null;
			int time= Integer.parseInt(st.nextToken());
			int colors= Integer.parseInt(st.nextToken());
			float phatPay= Float.parseFloat(st.nextToken());
			System.err.println("parameters: "+ time +", "+ phatPay);
			game = new BNS.coloring.ConsensusGame (gp, colors, time, phatPay, 0,
				new TreeMap<Character, Vector<Float>>(), 1, false, false);
		} catch(Exception e) { System.err.println("problem: "+ e); }
		return game;
		}
	
	/** sole constructor
		@param gp 		  	The GraphPack to use in this game.
	 * @param colors 	  	The number of different colors to use.
	 * @param time 	  		The maximum number of seconds the game will be allowed to run.
	 * @param winPayoff		The dollar reward for having your node well-colored.
	 * @param costToMove	The cost to change colors (in dollars).
	 * @param bonusMap 		A map from node classes to bonus vectors for those classes.
	 * @param ident	  		Whether or not we scramble the colors (colorMapIsIdentity).
	 * @param progBar	  	Whether or not the progress bar is shown.
	 * @param timeBar	  	Whether or not the elapsed time bar is shown. 
		*/
	public ConsensusGame(GraphPack gp, int colors, int time, float winPayoff, float costToMove, 
		TreeMap<Character, Vector<Float>> bonusMap, int ident, boolean progBar, boolean timeBar) {
		super(gp, colors, time, winPayoff, costToMove, bonusMap, ident, progBar, timeBar);
		this.bonus = bonusMap;
		otherInits (winPayoff, costToMove);
		}
	
	/** These inits override those in ColoringGame. Defines the payoff definition differently. */	
	protected void otherInits (float pay, float costToMove) {
		payOff= new float[]{0,pay};
		payOffStr= new String[payOff.length];
		for (int i=0; i<payOff.length; i++) {
			payOffStr[i]= String.format("$%.2f",payOff[i]);
			}
		payoffDefn = "<html><div align=\"center\">You will earn "+ payOffStr[1] + " if everyone's" +
			" color is the same, otherwise " + payOffStr[0] + ".";
		if (costToMove != 0)
			payoffDefn += "<br />You will lose $" + costToMove + " every time you change colors." +
				"</div></html>";
		else
			payoffDefn += "</div></html>";
	}
		
	public String getTitle() { return "Consensus Game"; }
	
	/** gives a long description of this game; used to inform supervisor about game choice. */
	public String getInfo() { 
		return getTitle() +" of size "+ getSize() +"\n"
		+" number of colours allowed= "+ colorChoices +"\n"
		+" losePayoff="+ payOff[0] +" winPayoff="+ payOff[1] +"\n"
		+" bonus=" + bonus + "\n"
		+" time allowed="+ timeLimit +"\n"
		+" graphpack info= "+ grpk.getInfo();
		}
	
	/** returns a measure of "social welfare" indicating how the group as a whole is doing */
	protected int getProgress() { return grpk.graph.satEdges(false); }
		
	} // EOC ConsensusGame
